home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Windows 95 with MFC
/
Programming Windows 95 with MFC (Microsoft Programming Series)(097-0001465)(1996).iso
/
NT
/
CODE
/
CHAP14
/
THREADS
/
THREADS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-05
|
6KB
|
213 lines
//***********************************************************************
//
// Threads.cpp
//
//***********************************************************************
#include <afxwin.h>
#include <math.h>
#include "Resource.h"
#include "Threads.h"
#define RADIUS 120
CMyApp myApp;
/////////////////////////////////////////////////////////////////////////
// CMyApp member functions
BOOL CMyApp::InitInstance ()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
// CMainWindow message map and member functions
BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_CLOSE ()
ON_COMMAND_RANGE (IDM_THREAD_1, IDM_THREAD_4, OnToggleThread)
ON_COMMAND (IDM_FRIENDLY_THREADS, OnFriendlyThreads)
ON_UPDATE_COMMAND_UI_RANGE (IDM_THREAD_1, IDM_THREAD_4,
OnUpdateThreadUI)
ON_UPDATE_COMMAND_UI (IDM_FRIENDLY_THREADS,
OnUpdateFriendlyThreadsUI)
ON_COMMAND (IDM_EXIT, OnExit)
END_MESSAGE_MAP ()
CMainWindow::CMainWindow ()
{
m_bFriendlyThreads = FALSE;
for (int i=0; i<4; i++) {
m_pThread[i] = NULL;
m_bContinue[i] = FALSE;
}
CString strWndClass = AfxRegisterWndClass (
0,
myApp.LoadStandardCursor (IDC_ARROW),
(HBRUSH) (COLOR_3DFACE + 1),
myApp.LoadStandardIcon (IDI_APPLICATION)
);
Create (strWndClass, "Threads", WS_OVERLAPPEDWINDOW, rectDefault,
NULL, MAKEINTRESOURCE (IDR_MAINFRAME));
LoadAccelTable (MAKEINTRESOURCE (IDR_MAINFRAME));
}
BOOL CMainWindow::PreCreateWindow (CREATESTRUCT& cs)
{
if (!CFrameWnd::PreCreateWindow (cs))
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
return TRUE;
}
void CMainWindow::OnClose ()
{
for (int i=0; i<4; i++) {
if (m_pThread[i] != NULL)
delete m_pThread[i];
}
CFrameWnd::OnClose ();
}
void CMainWindow::OnToggleThread (UINT nID)
{
static int nCoords[4][2] = {
RADIUS, -RADIUS, // Thread 1
RADIUS * 3, -RADIUS, // Thread 2
RADIUS, -RADIUS * 3, // Thread 3
RADIUS * 3, -RADIUS * 3 // Thread 4
};
UINT i = nID - IDM_THREAD_1;
if (m_pThread[i] == NULL) { // Create a thread
THREADPARMS* pThreadParms = new THREADPARMS;
pThreadParms->point.x = nCoords[i][0];
pThreadParms->point.y = nCoords[i][1];
pThreadParms->pContFlag = &m_bContinue[i];
pThreadParms->pFriendFlag = &m_bFriendlyThreads;
pThreadParms->lParam = (LPARAM) this;
m_bContinue[i] = TRUE;
m_pThread[i] = AfxBeginThread (ThreadFunc, pThreadParms);
}
else { // Terminate a thread
HANDLE hThread = m_pThread[i]->m_hThread;
m_bContinue[i] = FALSE;
::WaitForSingleObject (hThread, INFINITE);
m_pThread[i] = NULL;
}
}
void CMainWindow::OnFriendlyThreads ()
{
m_bFriendlyThreads = m_bFriendlyThreads ? FALSE : TRUE;
}
void CMainWindow::OnUpdateFriendlyThreadsUI (CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (m_bFriendlyThreads);
}
void CMainWindow::OnExit ()
{
SendMessage (WM_CLOSE, 0, 0);
}
void CMainWindow::OnUpdateThreadUI (CCmdUI* pCmdUI)
{
UINT i = pCmdUI->m_nID - IDM_THREAD_1;
CString string;
if (m_pThread[i] == NULL)
string.Format ("Start Thread &%d\tF%d", i + 1, i + 1);
else
string.Format ("Terminate Thread &%d\tF%d", i + 1, i + 1);
pCmdUI->SetText (string);
}
void CMainWindow::DrawHand (CDC* pDC, int nLength, int nScale,
int nDegrees, COLORREF crColor)
{
CPoint point[4];
double nRadians = (double) nDegrees * 0.017453292;
point[0].x = (int) (nLength * sin (nRadians));
point[0].y = (int) (nLength * cos (nRadians));
point[2].x = -point[0].x / nScale;
point[2].y = -point[0].y / nScale;
point[1].x = -point[2].y;
point[1].y = point[2].x;
point[3].x = -point[1].x;
point[3].y = -point[1].y;
CPen pen (PS_SOLID, 0, crColor);
CPen* pOldPen = pDC->SelectObject (&pen);
pDC->MoveTo (point[0]);
pDC->LineTo (point[1]);
pDC->LineTo (point[2]);
pDC->LineTo (point[3]);
pDC->LineTo (point[0]);
pDC->SelectObject (pOldPen);
}
UINT CMainWindow::ThreadFunc (LPVOID pParam)
{
static COLORREF crColors[8] = {
RGB ( 0, 0, 0), // Black
RGB ( 0, 0, 255), // Blue
RGB ( 0, 255, 0), // Green
RGB ( 0, 255, 255), // Cyan
RGB (255, 0, 0), // Red
RGB (255, 0, 255), // Magenta
RGB (255, 255, 0), // Yellow
RGB (255, 255, 255) // White
};
THREADPARMS* pThreadParms = (THREADPARMS*) pParam;
CPoint point = pThreadParms->point;
BOOL* pContFlag = pThreadParms->pContFlag;
BOOL* pFriendFlag = pThreadParms->pFriendFlag;
CMainWindow* pWnd = (CMainWindow*) pThreadParms->lParam;
delete pThreadParms;
int nMinute = 0;
int nIndex = 0;
while (*pContFlag) {
CDC* pDC = pWnd->GetDC ();
pDC->SetMapMode (MM_LOENGLISH);
CPoint org = point;
pDC->LPtoDP (&org);
pDC->SetViewportOrg (org.x, org.y);
pWnd->DrawHand (pDC, RADIUS, 8, nMinute * 6, crColors[nIndex]);
pWnd->ReleaseDC (pDC);
if (++nMinute == 60) {
nMinute = 0;
if (++nIndex == 8)
nIndex = 0;
}
if (*pFriendFlag)
::Sleep (0);
}
return 0;
}